(() => {
    // 布尔类型 --> boolean
    // 基本语法
    // let 变量名：数据类型
    let flag: boolean = true
    console.log(flag)

    // 数字类型 --> number
    let a1:number = 10  // 十进制
    let a2:number = 0b1010 // 二进制
    let a3:number = 0o12  // 十进制
    let a4:number = 0xa // 二进制
    console.log(a1)
    console.log(a2)
    console.log(a3)
    console.log(a4)

    // 字符串类型 --> string
    let str1: string = '床前明月光'
    let str2: string = '小明去开窗'
    let str3: string = '遇到一耳光'
    let str4: string = '牙齿掉光光'
    console.log(`${str1},${str2},${str3},${str4}`)

    // 字符串和数字之间能够一起拼接
    let str5: string = '我有这么多的钱'
    let num: number = 1000
    console.log(str5 + num)

    // undefined 和null都可以作为其它类型的子类型
    let und: undefined = undefined
    let nll: null = null
    console.log(und)
    console.log(nll)

    // 数组类型
    // 数组定义方式
    // 语法：let 变量名：数据类型[] = [值1,值2]
    let arr1: number[] = [10, 20, 30, 40, 50]
    console.log(arr1)
    // 数组定义方式2：泛型的写法
    // 语法：let 变量名：Array<数据类型> = [值1,值2]
    let arr2: Array<number> = [10, 20, 30, 40, 50]
    console.log(arr2)

    // 元组类型,在定义数组时候，类型和数据的个数就已经限定
    let arr3: [string, number, boolean] = ['小明', 100, true]
    console.log(arr3)

    // 枚举类型
    enum Color {
        red,
        blue,
        green
    }
    let color: Color = Color.red
    console.log(color)
    console.log(Color.red, Color.blue, Color.green)
    console.log(Color[2])

    // any 类型
    let str: any = 100
    str = '年少不知富婆好，错把少女当作宝'
    console.log(str)
    // 当一个数组中要存储多个数据且类型不确定
    let arr: any[] = [100, '年少不知软饭香，错把青春倒插秧']
    console.log(arr)

    // void 类型 在函数声明时候，小括号后面使用void代表函数没有返回值
    function showMsg(): void {
        console.log('只要富婆住，连夜搬进大别墅')
        return undefined
    }
    console.log(showMsg())
    // 定义void的变量，可以接受一个undefined，意义不大
    let vd: void = undefined
    console.log(vd)

    // object类型
    // 定义一个函数，参数是obj类型，返回值也是obj类型
    function getObj(obj: object): object{
        console.log(obj)
        return {
            name: '小明',
            age: 27
        }
    }
    console.log(getObj({gender: '男'}))

    // 联合类型（Union Types）表示取值可以为多种类型中的一种
    // 需求1：定义一个函数得到一个数字或字符串
    function getString(str: number|string):string {
        return str.toString()   
    }
    console.log(getString('123'))
    console.log(getString(456))

    // 类型断言：告诉编译器，我知道我自己是什么类型，也知道自己在干嘛
    // 类型断言的语法方式：1：<类型>变量名
    // 类型断言的语法方式：1：值 as 类型
    // 需求2：定义一个函数得到一个数字或字符串的长度
    function getStringLen(str: number|string):number {
        if((<string>str).length) {
            return (str as string).length
        } else {
            return str.toString().length
        }
          
    }
    console.log(getStringLen('123'))

    // 类型推断：没有明确的指定类型的时候推测出一个类型
    let txt = 100
    // txt = '哈哈哈'   // 报错
    console.log(txt)

    let txt2 
    txt2 = 100
    txt2 = '哈哈哈'
    console.log(txt2)
})()